package com.jrx.anytxn.param.controller.cardRoll;

import com.alibaba.fastjson.JSONObject;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.i18n.response.TxnPage;
import com.jrx.anytxn.i18n.response.TxnRespResult;
import com.jrx.anytxn.param.config.AdjustLimitFileConfig;
import com.jrx.anytxn.param.entity.PrCardRollDetailInfo;
import com.jrx.anytxn.param.entity.PrCardRollInfo;
import com.jrx.anytxn.param.entity.PrCardRollToleadRecord;
import com.jrx.anytxn.param.plugins.DeleteLogHelper;
import com.jrx.anytxn.param.service.cardRoll.ICardRollService;
import com.jrx.anytxn.param.utils.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import jrx.auth.filter.service.InfoService;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;

@Api(tags = "卡卷管理相关接口")
@RestController
@RequestMapping(value = "/param/cardRoll")
public class CardRollAdminController {

    private static final Logger logger = LoggerFactory.getLogger(CardRollAdminController.class);

    @Autowired
    private ICardRollService cardRollService;

    @Autowired
    private AdjustLimitFileConfig adjustLimitFileConfig;

    @Autowired
    private InfoService infoService;

    @ApiOperation(value = "分页查询卡券列表信息", notes = "分页查询卡券列表信息-支持条件查询，模糊查询")
    @PostMapping(value = "/cardRollInfo/pageNum/{pageNum}/pageSize/{pageSize}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "页大小", required = true)})
    public TxnRespResult<TxnPage<PrCardRollInfo>> getAllPageByTenId(@PathVariable("pageNum") Integer pageNum, @PathVariable("pageSize") Integer pageSize,
                                                                    @RequestBody PrCardRollInfo prCardRollInfo) {
        TxnRespResult<TxnPage<PrCardRollInfo>> result = new TxnRespResult<>();
        TxnPage<PrCardRollInfo> response;
        try {
            prCardRollInfo.setTenantId(String.valueOf(infoService.getUser().getProjectId()));
            response = cardRollService.findInfoPageByTenantId(pageNum, pageSize, prCardRollInfo);
            result.getSuccess(response);
        } catch (TxnException e) {
            logger.error(e.getMessage(), e);
            result.getFail(e.getErrCode(), e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "分页查询卡券明细列表信息", notes = "分页查询卡券列表信息-支持条件查询，模糊查询")
    @PostMapping(value = "/cardRollDetail/pageNum/{pageNum}/pageSize/{pageSize}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "页大小", required = true)})
    public TxnRespResult<TxnPage<PrCardRollDetailInfo>> getAllPageByTenId(@PathVariable("pageNum") Integer pageNum, @PathVariable("pageSize") Integer pageSize,
                                                                    @RequestBody PrCardRollDetailInfo prCardRollDetailInfo) {
        TxnRespResult<TxnPage<PrCardRollDetailInfo>> result = new TxnRespResult<>();
        TxnPage<PrCardRollDetailInfo> response;
        try {
            prCardRollDetailInfo.setTenantId(String.valueOf(infoService.getUser().getProjectId()));
            response = cardRollService.findDetailPageByTenantId(pageNum, pageSize, prCardRollDetailInfo);
            result.getSuccess(response);
        } catch (TxnException e) {
            logger.error(e.getMessage(), e);
            result.getFail(e.getErrCode(), e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "新增卡券信息", notes = "新增卡券信息")
    @PostMapping("/add")
    public TxnRespResult<PrCardRollInfo> addCardRollInfo(@RequestBody PrCardRollInfo prCardRollInfo) {
        TxnRespResult<PrCardRollInfo> result = new TxnRespResult<>();
        PrCardRollInfo res;
        try {
            prCardRollInfo.setTenantId(String.valueOf(infoService.getUser().getProjectId()));
            prCardRollInfo.setUpdateBy(infoService.getUser().getUserName());
            res = cardRollService.addCardRollInfo(prCardRollInfo);
            result.getSuccess(res);
        } catch (TxnException e) {
            logger.error(e.getMessage(), e);
            result.getFail(e.getErrCode(), e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "根据租户ID和主键ID查询", notes = "根据租户ID和主键ID查询")
    @GetMapping(value = "/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键ID", required = true)
    })
    public TxnRespResult<PrCardRollInfo> getCardRollInfoById(@NotNull @PathVariable String id) {
        TxnRespResult<PrCardRollInfo> result = new TxnRespResult<>();
        PrCardRollInfo res;
        try {
            res = cardRollService.getCardRollInfoById(String.valueOf(infoService.getUser().getProjectId()), id);
            result.getSuccess(res);
        } catch (TxnException e) {
            logger.error(e.getMessage(), e);
            result.getFail(e.getErrCode(), e.getMessage());
        }
        return result;
    }

    /**
     * 更新卡券列表
     *
     * @param prCardRollInfo 更新卡券列表
     * @return 卡券列表
     * @throws TxnBizException 业务异常
     */
    @ApiOperation(value = "更新卡券列表", notes = "更新卡券列表")
    @PutMapping("/modifyCardRollInfo")
    public TxnRespResult<PrCardRollInfo> modifyCardRollInfo(@Valid @RequestBody PrCardRollInfo prCardRollInfo) {
        TxnRespResult<PrCardRollInfo> result = new TxnRespResult<>();
        PrCardRollInfo response;
        try {
            prCardRollInfo.setTenantId(String.valueOf(infoService.getUser().getProjectId()));
            prCardRollInfo.setUpdateBy(infoService.getUser().getUserName());
            response = cardRollService.modifyCardRollInfo(prCardRollInfo);
            result.getSuccess(response);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.getFail(TxnRespCode.BIZ_ERROR.getCode(), e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "删除卡券列表", notes = "删除卡券列表")
    @DeleteMapping(value = "/removeCardRoll/{id}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "卡券ID", required = true)
    })
    public TxnRespResult<Boolean> removeByTenIdAndCardRollId(@NotNull @PathVariable String id) {
        TxnRespResult<Boolean> result = new TxnRespResult<>();
        Boolean flag;
        try {
            flag = cardRollService.removeByTenIdAndCardRollId(id,String.valueOf(infoService.getUser().getProjectId()));
            result.getSuccess(flag);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.getFail(TxnRespCode.BIZ_ERROR.getCode(), e.getMessage());
        } finally {
            DeleteLogHelper.clearLocalHistory();
        }
        return result;
    }

    /**
     * 上传卡密表格文件
     *
     * @param file
     * @return
     */
    @PostMapping(value = "/uploadFile")
    @ApiOperation(value = "上传卡密表格文件", notes = "批量导入")
    public TxnRespResult<String> uploadCardPassFile(@RequestParam("file") MultipartFile file,@RequestParam String cardRollId) {
        String errTips = "";
        TxnRespResult<String> result = new TxnRespResult<>();
        if (!file.isEmpty()) {
            final String filename = file.getOriginalFilename();
            assert filename != null;

            if (filename.endsWith(".xlsx") || filename.endsWith(".xls")) {
                boolean isXlsx = filename.endsWith("x");

                List<List<String>> list = null;
                try (InputStream is = file.getInputStream()) {
                    list = ExcelUtil.analysisExcel(is, isXlsx, true);
                } catch (Exception e) {
                    logger.error("批量导入异常: {}", e.getMessage());
                    e.printStackTrace();
                    errTips = "批量导入异常";
                    result.getFail(TxnRespCode.BIZ_ERROR.getCode(), errTips);
                }
                if (list != null) {
                    logger.info("上传文件解析记录数: {}", list.size());
                    try {
                        StringBuffer tips = new StringBuffer();//上传失败提示信息
                        PrCardRollInfo prCardRollInfo = cardRollService.batchSaveQrcodes(list, String.valueOf(infoService.getUser().getProjectId()), infoService.getUser().getUserName(),cardRollId,tips);
                        result.setData(JSONObject.toJSONString(prCardRollInfo));
                        if (!StringUtils.isEmpty(String.valueOf(tips))){
                            String tip = Arrays.stream(String.valueOf(tips).split(",")).filter(s -> !s.isEmpty()).reduce((a,b) -> a+","+b).orElse("");
                            result.getFail(111111, tip); //上传失败提示信息
                        }
                    } catch (TxnException e) {
                        result.getFail(e.getErrCode(), e.getMessage());
                    }
                } else {
                    logger.warn("上传文件解析内容为空");
                    errTips = "上传文件解析内容为空";
                }

            } else {
                errTips = "仅支持xlsx或xls格式文件";
            }
        } else {
            errTips = "上传文件内容为空";
        }

        if (!errTips.isEmpty()) {
            result.getFail(TxnRespCode.BIZ_ERROR.getCode(), errTips);
        }
        return result;
    }


    @ApiOperation(value = "下载卡密模板", notes = "下载卡密模板")
    @GetMapping(value = "/downLoad")
    public void downLoadCoupon(HttpServletResponse response, @RequestParam("filePath") String filePath,
                               @RequestParam String tenantId) {
        String templatePath = adjustLimitFileConfig.getBasePath() + "/" + tenantId + "/";
        logger.info("下载卡密模板地址：{}", templatePath);
        response.setContentType("application/csv");
        File file = new File(templatePath + filePath);
        try (FileInputStream fileInputStream = new FileInputStream(file);
             OutputStream outputStream = response.getOutputStream();) {
            IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);
            response.setHeader("Content-Disposition", "inline; filename= couponTemplate.csv");
            outputStream.flush();
        } catch (Exception e) {
            logger.error("下载卡密模板异常", e);
        }
    }

    @ApiOperation(value = "分页查询卡券导入记录信息", notes = "分页查询卡券导入记录信息-支持条件查询，模糊查询")
    @PostMapping(value = "cardRollToleadRecord/pageNum/{pageNum}/pageSize/{pageSize}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "页大小", required = true)})
    public TxnRespResult<TxnPage<PrCardRollToleadRecord>> getAllPageByTenId(@PathVariable("pageNum") Integer pageNum, @PathVariable("pageSize") Integer pageSize,
                                                                          @RequestBody PrCardRollToleadRecord prCardRollToleadRecord) {
        TxnRespResult<TxnPage<PrCardRollToleadRecord>> result = new TxnRespResult<>();
        TxnPage<PrCardRollToleadRecord> response;
        try {
            prCardRollToleadRecord.setTenantId(String.valueOf(infoService.getUser().getProjectId()));
            prCardRollToleadRecord.setUpdateBy(infoService.getUser().getUserName());
            response = cardRollService.findToleadRecordByTenantId(pageNum, pageSize, prCardRollToleadRecord);
            result.getSuccess(response);
        } catch (TxnException e) {
            logger.error(e.getMessage(), e);
            result.getFail(e.getErrCode(), e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "卡密提取", notes = "卡密提取")
    @PostMapping("/rightsPassExtract")
    public TxnRespResult<PrCardRollDetailInfo> rightsPassExtract(@RequestBody PrCardRollDetailInfo prCardRollDetailInfo) {
        TxnRespResult<PrCardRollDetailInfo> result = new TxnRespResult<>();
        PrCardRollDetailInfo res;
        try {
            prCardRollDetailInfo.setTenantId(String.valueOf(infoService.getUser().getProjectId()));
            prCardRollDetailInfo.setUpdateBy(infoService.getUser().getUserName());
            res = cardRollService.rightsPassExtract(prCardRollDetailInfo);
            result.getSuccess(res);
        } catch (TxnException e) {
            logger.error(e.getMessage(), e);
            result.getFail(e.getErrCode(), e.getMessage());
        }
        return result;
    }

}
